package com.spring.springboot.sys.util;

import com.spring.springboot.sys.base.ServiceException;
import com.spring.springboot.sys.core.config.SendMessageProperties;
import com.spring.springboot.sys.core.constant.BusinessConstant;
import com.spring.springboot.sys.core.constant.ConstantsContext;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Random;

/**
 * @author 宋义州
 * @date 2022-08-10  23:06
 * @description 腾讯云短信发送
 */
@Component
public class SendMessageUtil {

    @Resource
    private SmsClient client;

    private static SmsClient smsClient;

    @PostConstruct
    public void initSmsClient() {
        smsClient = client;
    }

    public static SendSmsResponse sendMessage(String[] phone) {
        try {
            SendMessageProperties properties = ConstantsContext.getSendMessageProperties();

            /**
             * 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
             * 你可以直接查询SDK源码确定接口有哪些属性可以设置
             * 属性可能是基本类型，也可能引用了另一个数据结构
             * 推荐使用IDE进行开发，可以方便地跳转查阅各个接口和数据结构的文档说明
             */
            SendSmsRequest req = new SendSmsRequest();
            /**
             * 填充请求参数,这里request对象的成员变量即对应接口的入参
             * 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
             * 基本类型的设置:
             * 帮助链接：
             * 短信控制台: https://console.cloud.tencent.com/smsv2
             * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81
             */

            /**
             * 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666
             * 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
             */
            req.setSmsSdkAppid(properties.getMsgSdkAppId());

            /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
            // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
            req.setSign(properties.getMsgSignName());

            /**
             * 模板 ID: 必须填写已审核通过的模板 ID
             * 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
             */
            req.setTemplateID(properties.getMsgTemplateId());

            /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
            String[] templateParamSet = {generateValidateCode(BusinessConstant.IntNum.NUM_FOUR).toString(), BusinessConstant.StringNum.NUM_FIVE};
            req.setTemplateParamSet(templateParamSet);

            /**
             * 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号
             */
            req.setPhoneNumberSet(phone);

            /* 用户的 session 内容（无需要可忽略）: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
            String sessionContext = "";
            req.setSessionContext(sessionContext);

            /* 短信码号扩展号（无需要可忽略）: 默认未开通，如需开通请联系 [腾讯云短信小助手] */
            String extendCode = "";
            req.setExtendCode(extendCode);

            /* 国际/港澳台短信 SenderId（无需要可忽略）: 国内短信填空，默认未开通，如需开通请联系 [腾讯云短信小助手] */
            String senderid = "";
            req.setSenderId(senderid);

            /**
             * 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应
             */
            return smsClient.SendSms(req);
        } catch (TencentCloudSDKException e) {
            throw new ServiceException(500, "短信发送失败！请联系开发人员！");
        }
    }

    /**
     * 生成随机验证码4/6位数
     *
     * @param length 生成验证码的位数
     * @return Integer 验证码
     */
    public static Integer generateValidateCode(int length) {
        int code;
        if (length == 4) {
            //生成随机数，最大为9999
            code = new Random().nextInt(9999);
            if (code < 1000) {
                //保证随机数为4位数字
                code = code + 1000;
            }
        } else if (length == 6) {
            //生成随机数，最大为999999
            code = new Random().nextInt(999999);
            if (code < 100000) {
                //保证随机数为6位数字
                code = code + 100000;
            }
        } else {
            throw new RuntimeException("只能生成4位或6位数字验证码");
        }
        return code;
    }

}
